package serialPort

import com.fazecast.jSerialComm.SerialPort
import com.fazecast.jSerialComm.SerialPortDataListener
import com.fazecast.jSerialComm.SerialPortEvent
import com.hailiao.hlbdcore.base.HLBDClient

/**
 * PC串口通讯工具
 * @Author: D10NG
 * @Time: 2021/7/19 4:48 下午
 */
class PCSerialPortManager : HLBDClient() {

    companion object {
        @Volatile
        private var INSTANCE: PCSerialPortManager? = null

        @JvmStatic
        fun instance() =
            INSTANCE?: synchronized(this) {
                INSTANCE?: PCSerialPortManager().also {
                    INSTANCE = it
                }
            }
    }

    /** 正在使用的端口 */
    private var mUsePort: SerialPort? = null

    /**
     * 获取通讯端口列表
     * @return List<SerialPort>
     */
    fun getSerialPortList(): List<SerialPort> =
        SerialPort.getCommPorts().toList()

    /**
     * 获取正在使用的端口
     * @return SerialPort?
     */
    fun getUsePort(): SerialPort? = mUsePort

    /**
     * 获取正在使用的端口的名字
     * @return String
     */
    fun getUsePortName(): String =
        mUsePort?.systemPortName?: "NULL"

    /**
     * 打开端口
     * @param port SerialPort
     * @param baudRate BaudRate
     * @return Boolean
     */
    fun openPort(port: SerialPort, baudRate: BaudRate): Boolean {
        port.setComPortParameters(baudRate.intValue, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY)
        val isSuccess = port.openPort()
        if (isSuccess) {
            port.addDataListener(object : SerialPortDataListener {
                override fun getListeningEvents(): Int =
                    SerialPort.LISTENING_EVENT_DATA_WRITTEN or SerialPort.LISTENING_EVENT_DATA_RECEIVED

                override fun serialEvent(event: SerialPortEvent?) {
                    when(event?.eventType) {
                        SerialPort.LISTENING_EVENT_DATA_WRITTEN -> {
                            println("数据发送成功！")
                        }
                        SerialPort.LISTENING_EVENT_DATA_RECEIVED -> {
                            println("接收到数据！")
                            val receive = event.receivedData
                            handlerReceive(port.systemPortName, receive)
                        }
                    }
                }
            })
            mUsePort = port
        }
        return isSuccess
    }

    /**
     * 关闭端口
     */
    fun closePort() {
        mUsePort?.apply {
            removeDataListener()
            closePort()
            println("已关闭端口")
        }
    }

    /**
     * 发送消息
     * @param device String
     * @param data ByteArray
     * @return Boolean
     */
    override suspend fun send(device: String, data: ByteArray): Boolean {
        return mUsePort?.writeBytes(data, data.size.toLong()) == data.size
    }
}

/**
 * 波特率
 * @property intValue Int
 * @constructor
 */
enum class BaudRate(val intValue: Int) {

    B_4800(4800),

    B_9600(9600),

    B_19200(19200),

    B_38400(38400),

    B_57600(57600),

    B_115200(115200),
}